#ifndef _DISH_H
#define _DISH_H

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#define ERROR(_x) write(STDERR_FILENO,_x,strlen(_x))
#define WRITE(_x) write(STDOUT_FILENO,_x,strlen(_x))

#define CMD_IMMEDIATE	0x01
#define CMD_WAIT	0x02
#define	CMD_CONDITIONAL	0x04
#define CMD_BACKGROUND	0x08
#define CMD_EXEC	0x10
#define CMD_INVERSE	0x20

typedef struct cmd_fileno_s {
	int fd;
	char* name;
} cmd_fileno_t;

typedef struct cmd_s {
	struct cmd_s *prev;
	struct cmd_s *next;
	int flags;
	char* cmd;
	int argc;
	char** argv;
	char** env;
	cmd_fileno_t stdin;
	cmd_fileno_t stdout;
	cmd_fileno_t stderr;
	pid_t pid;
	int estate;
} cmd_t;

/* defined in main.c */
void exit_state(int n);

/* defined in lib.c */
unsigned int hash(char* str);
void debug(char* fmt, ...);
uid_t get_uid(char* name);
gid_t get_gid(char* name);
char* get_username(void);
char* trim(char* str);
int is_dir(char* p);
int is_file(char* p);
int is_exec(char* p);
int is_something(char* p);
void usage(void);
int error(char* a);

/* defined in tokenize.c */
char** tokenize(char* str, int *count);
char* tok_last(char* str);

/* defined in parse.c */
int parse_line(char* line, int in, int out, int err);
int parse_line_buff(char* line, int in, char* out, int outl, int err);
int parse_stream(int in, int out, int err);
int parse_interactive(int in, int out, int err);

/* defined in builtin.c */
int builtin_check(char* fn);
int builtin_exec(int argc, char** argv, char** env, int in, int out, int err);

/* defined in clist.c */
char** clist_gen(char* v, ...);
void clist_free(char** da);
char** clist_append(char** da, ...);
char** clist_copy(char** da, int start, int count);
int clist_find(char** da, char* str);
int clist_nfind(char** da, char* str);
int clist_findn(char** da, char* str);
char** clist_replacev(char** da, int i, char* v);
int clist_count(char** da);
void clist_remove(char** da, char *v);
char* clist_join(char** da, char* j, int o);
char** clist_split(char* str, char* s);
char* clist_last(char** da);

/* defined in fork.c */
int forkit(cmd_t *cmd);

/* defined in tty.c */
int set_tty_raw(void);
int set_tty_cooked(void);
unsigned char getch(int in);

/* defined in history.c */
void history_load(void);
void history_save(void);
void history_add(char* str);
char* history_prev(void);
char* history_next(void);

/* defined in tabfill.c */
char* tabfill_get(char* buff);
void tabfill_clear(void);

#endif
